﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace App.Untiys
{
    public static class DataTranf
    {
        /// 根据传入URL，Get请求获取HTML
        /// </summary>
        public static string GetHTML(string url, string encodeType = "utf-8", string contentType = "application/x-www-form-urlencoded")
        {
            try
            {
                HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url);
                hwr.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
                hwr.ContentType = contentType;
                hwr.Timeout = 90000;// 19990;
                CookieContainer cc = new CookieContainer();
                hwr.CookieContainer = cc;
                HttpWebResponse hwrs = (HttpWebResponse)hwr.GetResponse();
                Stream myStream = hwrs.GetResponseStream();
                Encoding encoding = Encoding.GetEncoding(encodeType);
                StreamReader sr = new StreamReader(myStream, encoding);
                string strResult = sr.ReadToEnd();
                hwrs.Close();
                return strResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

        }

        /// <summary>
        /// 图片转字节
        /// </summary>
        /// <param name="imgPath"></param>
        /// <returns></returns>
        public static byte[] ImageToBytes(string imgPath)
        {
            FileStream fileStream = new FileStream(imgPath, FileMode.Open);
            byte[] array = new byte[fileStream.Length];
            fileStream.Read(array, 0, array.Length);
            fileStream.Close();
            return array;
        }

        /// <summary>
        /// 图片对象转Base64
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        public static string ImageToBase64(string imagePath)
        {
            using (Image image = Image.FromFile(imagePath))
            {
                using (MemoryStream m = new MemoryStream())
                {
                    // 将图像保存到内存流中，指定格式为Jpeg或Png等
                    image.Save(m, image.RawFormat);
                    byte[] imageBytes = m.ToArray();

                    // 将字节数组转换为Base64字符串
                    string base64String = Convert.ToBase64String(imageBytes);
                    return base64String;
                }
            }
        }

        /// <summary>
        /// 根据传入URL，POST请求获取HTML
        /// </summary>
        public static string PostHTML(string url, string postData, string encodeType = "UTF-8", string contentType = "application/json;charset=UTF-8")
        {
            try
            {
                string serviceAddress = url;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
                request.Method = "POST";
                request.ContentType = contentType;
                string strContent = postData;
                var bytes = Encoding.GetEncoding(encodeType).GetBytes(strContent);
                using (var dataStream = request.GetRequestStream())
                {
                    dataStream.Write(bytes, 0, bytes.Length);
                    dataStream.Close();
                }
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                string encoding = response.ContentEncoding;
                if (encoding == null || encoding.Length < 1)
                {
                    encoding = "UTF-8"; //默认编码  
                }
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
                string strResult = reader.ReadToEnd();
                return strResult;
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 密码复杂度校验
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static bool IsPasswordComplex(string password)
        {
            // 正则表达式规则解释：
            // ^ 表示字符串的开始
            // (?=.*[A-Z]) 表示至少包含一个大写字母
            // (?=.*[a-z]) 表示至少包含一个小写字母
            // (?=.*[0-9]) 表示至少包含一个数字
            // (?=.*[!@#$%^&*]) 表示至少包含一个特殊字符
            // .{8,} 表示长度至少为8个字符
            // $ 表示字符串的结束
            string pattern = "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]).{8,}$";

            return Regex.IsMatch(password, pattern);
        }

        /// <summary>
        /// 将实体中String类型的字段 NULL 替换为 "" 不为 NULL 则去除空格
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T ToTrimString<T>(this T t)
        {
            try
            {
                if (t == null)
                    return default(T);
                Type type = t.GetType();
                PropertyInfo[] props = type.GetProperties();
                Parallel.ForEach(props, p =>
                {
                    if (p.PropertyType.Name.Equals("String"))
                    {
                        var tmp = (string)p.GetValue(t, null);
                        p.SetValue(t, tmp == null ? "" : tmp.Trim(), null);
                    }
                });
                return t;
            }
            catch
            {
                return default(T);
            }
        }

        ///// <summary>
        ///// 对象去除去除空格
        ///// </summary>
        ///// <param name="obj">对象</param>
        ///// <returns></returns>
        //public static object TrimString(this object obj)
        //{
        //    try
        //    {
        //        Type type = obj.GetType();
        //        PropertyInfo[] props = type.GetProperties();

        //        Parallel.ForEach(props, p =>
        //        {
        //            if (p.PropertyType.Name.Equals("String"))
        //            {
        //                var tmp = (string)p.GetValue(obj, null);
        //                p.SetValue(obj, tmp.Trim(), null);
        //            }
        //        });

        //        return obj;
        //    }
        //    catch
        //    {
        //        return obj;
        //    }
        //}

        /// <summary>
        /// 返回两个 double 中间随机
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static double ToNextDouble(this Random random, double minValue, double maxValue)
        {
            if (random == null)
                return 0.0d;
            return random.NextDouble() * (maxValue - minValue) + minValue;
        }

        /// <summary>
        /// 转换成中文日期格式
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToZh_Date(this DateTime obj)
        {
            return obj == null ? "" : obj.ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 转换成中文日期+时间格式
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToZh_DateTime(this DateTime obj)
        {
            return obj == null ? "" : obj.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 图片转ToBase64
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        //public static string ToBase64(this System.Drawing.Image file)
        //{
        //    using (MemoryStream memoryStream = new MemoryStream())
        //    {
        //        file.Save(memoryStream, file.RawFormat);
        //        byte[] imageBytes = memoryStream.ToArray();
        //        return Convert.ToBase64String(imageBytes);
        //    }
        //}

        /// <summary>
        /// 转换成整数型
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static double ToDoubleEx(this object obj)
        {
            double tempVal = 0;
            if (obj == null) return tempVal;
            double.TryParse(obj.ToStringEx(), out tempVal);
            return tempVal;
        }

        /// <summary>
        /// 转换成整数型
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static decimal ToDecimalEx(this object obj)
        {
            decimal tempVal = 0;
            if (obj == null) return tempVal;
            decimal.TryParse(obj.ToStringEx(), out tempVal);
            return tempVal;
        }

        /// <summary>
        /// 删除指定位置字符
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="strart"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string ToRemoveEx(this string obj, int strart, int len)
        {
            try
            {
                if (string.IsNullOrEmpty(obj))
                    return "";
                return obj.Remove(strart, len);
            }
            catch
            {
                return "";
            }
        }

        /// <summary>
        /// 字符串转 符号 分割以后的 数组
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="split">分割符号</param>
        /// <param name="removeEmptyEntries">是否去掉空格字符</param>
        /// <returns></returns>
        public static List<string> ToSplitArrayEx(this object obj, char split, bool removeEmptyEntries = true)
        {
            if (removeEmptyEntries)
                return obj == null ? new List<string>() : obj.ToString().Split(new char[] { split }, StringSplitOptions.RemoveEmptyEntries).ToArray().ToList();
            return obj == null ? new List<string>() : obj.ToString().Split(new char[] { split }, StringSplitOptions.None).ToArray().ToList();
        }

        /// <summary>
        /// 数组 转 符号分割的字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="split">分割符</param>
        /// <param name="removeEmptyEntries">是否去掉空值</param>
        /// <returns></returns>
        public static string ToSplitStringEx(this List<string> obj, string split, bool removeEmptyEntries = true)
        {
            if (removeEmptyEntries)
            {
                List<string> objNew = new List<string>();
                obj.ForEach(item =>
                {
                    if (!string.IsNullOrWhiteSpace(item))
                        objNew.Add(item);
                });
                return string.Join(split, objNew);
            }
            return string.Join(split, obj);
        }

        /// <summary>
        /// 数组 转 符号分割的字符串    补上单引号
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="split">分割符</param>
        /// <param name="removeEmptyEntries">是否去掉空值</param>
        /// <returns></returns>
        public static string ToSplitStringPlusEx(this List<string> obj, string split, bool removeEmptyEntries = true)
        {
            List<string> tempObj = new List<string>();
            obj.ForEach(res =>
            {
                tempObj.Add($"'{res}'");
            });
            if (removeEmptyEntries)
            {
                List<string> objNew = new List<string>();
                tempObj.ForEach(item =>
                {
                    if (!string.IsNullOrWhiteSpace(item))
                        objNew.Add(item);
                });
                return string.Join(split, objNew);
            }
            return string.Join(split, tempObj);
        }

        /// <summary>
        /// 数组 转 符号分割的字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="split">分割符号</param>
        /// <returns></returns>
        public static string ToSplitStringEx(this string[] obj, string split)
        {
            return string.Join(split, obj);
        }

        /// <summary>
        /// List 是否不为空
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsNotNull<T>(this List<T> obj)
        {
            if (obj == null) return false;
            if (obj.Count <= 0) return false;
            return true;
        }

        /// <summary>
        /// 是否为正确的日期
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsTrueDate(this string obj)
        {
            if (obj == null) return false;
            if (obj.Length <= 0) return false;
            DateTime date = DateTime.Now;
            return DateTime.TryParse(obj, out date);
        }

        /// <summary>
        /// 获取客户端IP
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        //public static string GetClientIp()
        //{
        //    string userIP = "";
        //    try
        //    {
        //        if (System.Web.HttpContext.Current == null
        //            || System.Web.HttpContext.Current.Request == null
        //            || System.Web.HttpContext.Current.Request.ServerVariables == null)
        //            return "";
        //        string CustomerIP = "";
        //        //CDN加速后取到的IP simone 090805
        //        CustomerIP = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
        //        if (!string.IsNullOrEmpty(CustomerIP))
        //        {
        //            return CustomerIP;
        //        }
        //        CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        //        if (!String.IsNullOrEmpty(CustomerIP))
        //        {
        //            return CustomerIP;
        //        }
        //        if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
        //        {
        //            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        //            if (CustomerIP == null)
        //                CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        //        }
        //        else
        //        {
        //            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        //        }
        //        if (string.Compare(CustomerIP, "unknown", true) == 0)
        //            return System.Web.HttpContext.Current.Request.UserHostAddress;
        //        return CustomerIP;
        //    }
        //    catch { }
        //    return userIP;
        //}

        /// <summary>
        ///  转json
        /// </summary>
        public static string ToJsonEx(this object data)
        {
            try
            {
                if (data == null || data is DBNull)
                    return "";
                return JsonConvert.SerializeObject(data);
            }
            catch
            {
                return "";
            }
        }

        /// <summary>
        /// 转数字
        /// </summary>
        public static int ToIntEx(this object data, int defaultVal = 0)
        {
            try
            {
                if (data == null || data is DBNull)
                    return defaultVal;
                return Convert.ToInt32(data);
            }
            catch
            {
                return defaultVal;
            }
        }

        /// <summary>
        /// 转数字 默认-1
        /// </summary>
        public static int ToPLCIntEx(this object data, int defaultVal = -1)
        {
            try
            {
                if (data == null || data is DBNull)
                    return defaultVal;
                return Convert.ToInt32(data);
            }
            catch
            {
                return defaultVal;
            }
        }

        public static int ToVWVal(this object data, int defaultVal = 0)
        {
            try
            {
                if (data == null || data is DBNull)
                    return defaultVal;
                string str = Regex.Replace(data.ToStringEx(), @"[^\d.\d]", "");
                return str.ToIntEx();
            }
            catch
            {
                return defaultVal;
            }
        }

        /// <summary>
        /// 将V10.1 这样的数据  解析程    list<int> {10.1}
        /// </summary>
        /// <param name="data"></param>
        /// <param name="defaultVal"></param>
        /// <returns></returns>
        public static List<int> To_PLC_V_SPLIT(this object data, float defaultVal = 0)
        {
            try
            {
                if (data == null || data is DBNull)
                    return null;
                string str = Regex.Replace(data.ToStringEx(), @"[^\d.\d]", "");
                var result = str.ToSplitArrayEx('.', true);
                List<int> ints = new List<int>();
                result.ForEach(res =>
                {
                    var temp = res.ToIntEx(-1);
                    if (temp != -1)
                        ints.Add(temp);
                });
                if (ints.IsNotNull())
                    if (ints.Count == 2)
                    {
                        //处理V1.1  ==  V0.9
                        if (ints[0] % 2 != 0)
                        {
                            ints[0] = ints[0] - 1;
                            ints[1] = ints[1] + 8;
                        }
                        return ints;
                    }

                return null;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 限制分页最大额为100
        /// </summary>
        /// <param name="data"></param>
        /// <param name="defaultVal"></param>
        /// <returns></returns>
        public static int ToLimitEx(this object data, int defaultVal = 0)
        {
            try
            {
                if (data == null || data is DBNull)
                    return defaultVal;
                int value = Convert.ToInt32(data);
                if (value > 100)
                    return 100;
                return Convert.ToInt32(data);
            }
            catch
            {
                return defaultVal;
            }
        }

        /// <summary>
        /// 转时间 错误则返回最小值 1900-10-01
        /// </summary>
        public static DateTime ToDefaultDateTimeEx(this object data)
        {
            try
            {
                if (data == null || data is DBNull)
                    return DateTime.Now;
                if (Convert.ToDateTime(data) <= Convert.ToDateTime("1900-10-01"))
                    return DateTime.Now;
                return Convert.ToDateTime(data);
            }
            catch
            {
                return DateTime.Now;
            }
        }

        /// <summary>
        /// 转时间
        /// </summary>
        public static DateTime ToDateTimeEx(this object data, DateTime defVal)
        {
            try
            {
                return data == null || data is DBNull ? defVal : Convert.ToDateTime(data);
            }
            catch
            {
                return defVal;
            }
        }

        /// <summary>
        /// 转double
        /// </summary>
        public static Double ToDoubleEx(this object data, double defVal)
        {
            try
            {
                return data == null || data is DBNull ? defVal : Convert.ToDouble(data);
            }
            catch
            {
                return defVal;
            }
        }

        /// <summary>
        /// 转为string
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ToStringEx(this object data)
        {
            try
            {
                return data == null || data is DBNull ? string.Empty : data.ToString();
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 返回时间戳
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static long ToTimeStampEx(this object data)
        {
            try
            {
                DateTime dt = DateTime.Now;
                DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                TimeSpan timeSpan = dt.Subtract(startTime);
                string timeStamp = timeSpan.Ticks.ToString();
                return Convert.ToInt64(timeStamp.Substring(0, timeStamp.Length - 7));
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 字符串比较，可以设置忽略大小写
        /// </summary>
        /// <param name="source"></param>
        /// <param name="value"></param>
        /// <param name="comparisonType"></param>
        /// <returns></returns>
        public static bool Contains(this string source, string value, StringComparison comparisonType)
        {
            return (source.IndexOf(value, comparisonType) >= 0);
        }

        /// <summary>
        /// 去除实体对象String中的首尾空格
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object ToTrimEx(this object obj)
        {
            try
            {
                Parallel.ForEach<PropertyInfo>(obj.GetType().GetProperties(), delegate (PropertyInfo p)
                {
                    if (p.PropertyType.Name == "String")
                    {
                        string str = (string)p.GetValue(obj, null);
                        if (!string.IsNullOrWhiteSpace(str))
                        {
                            p.SetValue(obj, str.Trim(), null);
                        }
                    }
                });
                return obj;
            }
            catch
            {
                return obj;
            }
        }


        /// <summary>
        /// 转为bool类型
        /// </summary>
        /// <param name="data"></param>
        /// <param name="defval"></param>
        /// <returns></returns>
        public static bool ToBoolEx(this object data, bool defval = false)
        {
            try
            {
                return data == null || data is DBNull ? defval : Convert.ToBoolean(data);
            }
            catch
            {
                return defval;
            }
        }


        /// <summary>
        /// 过滤html
        /// </summary>
        public static string FilterHtml(this string Htmlstring)
        {
            try
            {
                Htmlstring = Regex.Replace(Htmlstring, @"<style>[^<]*?</style>", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"<script [^>]*?>[^<]*?</script>", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"<[^>]*?>.*?</>", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"([\r])[\s]+", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"[\s]+", " ", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&nbsp;", "", RegexOptions.IgnoreCase);
                Htmlstring.Replace("&yen;", "");
                Htmlstring.Replace("\r", "");
                Htmlstring.Replace("\n", "");
                Htmlstring.Replace("\t", "");
                return Htmlstring;
            }
            catch
            {
                return string.Empty;
            }

        }

        /// <summary>
        /// 时间戳转为格式时间
        /// </summary>
        /// <param name="objDateTime"></param>
        /// <returns></returns>
        public static string ToTimestamp(this DateTime objDateTime)
        {
            try
            {
                TimeSpan ts = objDateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds * 1000).ToString();
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>  
        /// 时间戳转为C#格式时间  
        /// </summary>  
        /// <param name="timeStamp">Unix时间戳格式</param>  
        /// <returns>C#格式时间</returns>  
        public static DateTime StampToTime(this string timeStamp)
        {
            try
            {
                DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                long lTime = long.Parse(timeStamp + "0000000");
                TimeSpan toNow = new TimeSpan(lTime);
                return dtStart.Add(toNow);
            }
            catch
            {
                return DateTime.MinValue;
            }

        }

        /// <summary>
        /// Unicode解码
        /// </summary>
        public static string DeUnicode(this string str)
        {
            try
            {
                //最直接的方法Regex.Unescape(str);
                Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
                return reg.Replace(str, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); });
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Unicode编码
        /// </summary>
        public static string EnUnicode(this string str)
        {
            try
            {
                StringBuilder strResult = new StringBuilder();
                if (!string.IsNullOrEmpty(str))
                {
                    for (int i = 0; i < str.Length; i++)
                    {
                        strResult.Append("\\u");
                        strResult.Append(((int)str[i]).ToString("x"));
                    }
                }
                return strResult.ToString();
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 32位大写MD5加密
        /// </summary>
        public static string ToMD5_32(this string str)
        {
            try
            {
                string strMD5 = string.Empty;
                MD5 md5 = MD5.Create();//实例化一个md5对像
                // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
                byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
                // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
                for (int i = 0; i < s.Length; i++)
                {
                    // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 
                    strMD5 = strMD5 + s[i].ToString("X2");
                }
                return strMD5;
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 去除多余的字符串
        /// </summary>
        /// <param name="Str"></param>
        /// <param name="End"></param>
        /// <returns></returns>
        public static string RemoveString(string Str, int End)
        {
            if (Str.Length > End)
                return Str.Remove(End);
            else
                return Str;
        }

    }
}
